import CrawlerPlus from '../common/utils/CrawlerPlus'
import fs from 'fs'
import cheerio from 'cheerio'
import config from '../config/config'
type Id = number | string

interface List {
    text: string
    href: string
    author: string
    type: number
}

interface Details {
    chapterId: Id
    content: string
    next?: string
}

interface Chapter {
    name: string
    href: string
    content?: string
}

interface ChapterList {
    cover: string
    name: string
    bookId: number
    content: Chapter[]
    isLastPage?: boolean
}


interface String {
    replaceAll(input: string, output : string): any;
}
class Fiction {
    /**
     * 根据type所有的book列表
     * @param href 
     * @param page 
     * @param type 
     * @param title 
     * @returns 
     */
    public static async getAllListByType(href: string,page: number, type: number ,title?: string, ) {
        // let num: number = 1
        
        let arr: number[] = []
        for(let i = 0;i < page - 1;i++){
            arr.push(i)
            
        }
        let _list = await Promise.all(arr.map(async num => {
            const link = `${href}${num}.html`
            const res = await CrawlerPlus.getFictionData(link)
            if(!res){
                return false 
            }
            const $:cheerio.Root = cheerio.load(res)
            const nameCallback = (item: cheerio.Element)=> {
                return $(item).find('.blue').text()
            }
            const hrefCallback = (item: cheerio.Element)=> {
                return $(item).find('.blue').attr('href')!
            }
            const authorCallback = (item: cheerio.Element)=> {
                return $(item).text().split('/')[1]
            }
            const typeCallback = (item: cheerio.Element)=> {
                return type
            }
            console.log(num)
            return this.getListData($, '.cover .line', nameCallback,hrefCallback, authorCallback, typeCallback)
        }))
        const list: List[] = []
        _list.forEach(item=> {
            if(item){
                list.push(...item)
            }
        })
        title ? title = title : title = new Date().getTime().toString()
        // await fs.writeFileSync(`${process.cwd()}/src/public/json/${title}.json`,JSON.stringify(list))
        // title ? title = title : title = '1618891062426'
        // try {
        //     await fs.mkdirSync(`${process.cwd()}/src/public/json/${title}`)
        // } catch (error) {
        //    console.log(error) 
        // }
        
        // const list:List[] = JSON.parse(await fs.readFileSync(`${process.cwd()}/src/public/json/${title}.json`).toString())
        let content: string = ''
        // for(let i =0;i<list.length;i++){
        //     //{ text: '天道恩仇', href: '/s/138531.html', chapterId: 858 },
        // //     const item = list[i]
        // //     console.log('list for',item.href,item.chapterId)
        // //     try {
        // //         const details = await this.getDetails(item.href,item.chapterId,item.text)
        // //         content = `${content}\n${details}`
                
        // //     } catch (error) {
        // //         console.log(error)
        // //     }
        // //     if(i === 10){
        // //         break
        // //     }
        // //     //await getDetails(item.href,item.chapterId,title)
        // }
        // await fs.writeFileSync(`${process.cwd()}/${config.base}/public/txt/${title}_txt.txt`,content)
        return list
    }
    public static async getListData($:cheerio.Root, aClass: string, nameCallback: (data: cheerio.Element) => string, hrefCallback: (data: cheerio.Element) => string, authorCallback:  (data: cheerio.Element) => string, typeCallback:  (data: cheerio.Element) => number) {
        return new Promise<List[]>((resolve,reject)=>{
            let list: List[] = []
            $(aClass).each((index,item)=>{
                list.push({
                    text: nameCallback(item), //.split('章 ')[1],
                    href: hrefCallback(item),
                    author: authorCallback(item),
                    type: typeCallback(item)
                })
            })
            resolve(list)
        }).catch(error=>{
            console.log(error)
        })
    }
    
    // 获取章节列表
    public static async getChapterList(href: string, bookId: number) {
        let num: number = 1
        let list: ChapterList[]=[]
        for(let i = 1;i>-1;i++){
            
            console.log(num)
            try {
                const hrefArr = href.split('.html')
                let link = `${hrefArr[0]}_${num}.html`
                // if(num === 1){
                //     link = `${href}`
                // }
                console.log(link)
                const res = await CrawlerPlus.getFictionData(link)
                if(!res){
                    break 
                }
                const $:cheerio.Root = cheerio.load(res)
                const chapterList = await this.getChapterListData($,bookId)
                console.log(chapterList)
                if(!chapterList){
                    break
                }
                list.push(chapterList!)
                if(chapterList.isLastPage){
                    break
                }
                
    
            } catch (error) {
                console.log(error)
                break
            }
            num++
            
        }
        const data: {
            cover: string
            content: Chapter[]
        } = {
            cover: list[0].cover,
            content: []
        }
        
        list.forEach((item, index) => {
            data.content.push(...item.content)
        })
        return data
    }

    public static async getChapterListData($:cheerio.Root,bookId: number,){
        return new Promise<ChapterList>((resolve,reject)=>{
            const content: Chapter[] = []
            $('.intro.str-over-dot').next().next().next().find('li').each((index, item) => {
                content.push({
                    name: $(item).text().trim().replace('\n', ''),
                    href: $(item).find('a').attr('href')!
                })
            })
            const chapterList: ChapterList = {
                cover: $('.block_img2 img').attr('src')!,
                name: $('.block_txt2 h2 a').text().trim().replace('\n', ''),
                content,
                bookId,
                isLastPage: $('.intro.str-over-dot').next().find('li').first().find('a').attr('href') === content[content.length - 1].href
            }
            resolve(chapterList)
        }).catch(error=>{
            console.log(error)
        })
    }

    public static async getDetails(href: string,chapterId: Id, title: string) {
        let list:Details[] = []
        const res = await this.getDetailsData(href,chapterId)
        if(!res) {
            return ''
        }
        list.push(res)
        let next = res.next
        while(next) {
            let s = await this.getDetailsData(next,chapterId)
            if(!s) {
                break
            }
            next = s.next
            list.push(s)
        }
        let details:Details = list[0]
        let content: string = details.content
        list.forEach(element => {
            content = content + element.content
        });
        content = content.split('    ').join()
        details.content = content
        //await fs.writeFileSync(`${process.cwd()}/src/public/json/${title}/${chapterId}.json`,JSON.stringify(details))
        //console.log('list:' + JSON.stringify(details))
        return `## 第${chapterId}章 ${title} ${content}`
    }
    
    
    public static async getDetailsData(link:string,chapterId: Id){
        return new Promise<Details>(async (resolve,reject)=>{
            let details: Details
            const res = await CrawlerPlus.getFictionData(link)
            if(!res){
                reject(null)
                return 
            }
            const $:cheerio.Root = cheerio.load(res)
            const content = $('#TextContent').text()
            //const content = $('#TextContent').html() || ''
            let next = ''
            $('.fenyeA.button.sizebg.sizebgon.yeurl').each((index,item)=>{
                if($(item).text().indexOf('下一页') > -1){
                    next = $(item).attr('href') || ''
                }
            })
            details = {
                chapterId,
                content,
                next
            }
            resolve(details)
        }).catch(error=>{
            console.log(error)
        })
        
    
    }
}

export default Fiction